package com.bite.friend.manager;



import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.bit.common.redis.service.RedisService;
import com.bite.common.core.constants.CacheConstants;
import com.bite.common.core.domain.dto.BaseQueryTableDTO;
import com.bite.common.core.enums.MessageSendType;
import com.bite.common.core.utils.ThreadLocalUtil;
import com.bite.friend.domain.message.MessageText;
import com.bite.friend.domain.message.vo.MessageTextVO;
import com.bite.friend.mapper.message.MessageMapper;
import com.bite.friend.mapper.message.MessageTextMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class MessageCacheManager {

    @Autowired
    private RedisService redisService;

    @Autowired
    private MessageTextMapper messageTextMapper;

    @Autowired
    private MessageMapper messageMapper;


    public Long getUserMsgListSize() {
        return getUserMsgListSize(ThreadLocalUtil.getUserId());
    }

    public Long getUserMsgListSize(Long sendId) {
        String userMessageListKey = getUserMessageListKey(sendId);
        return redisService.getListSize(userMessageListKey);
    }

    public void refreshUserMsgListCache() {
        refreshMsgListCache(MessageSendType.USER, ThreadLocalUtil.getUserId());
    }

    public void refreshUserMsgListCache(Long userId) {
        refreshMsgListCache(MessageSendType.USER, userId);
    }

    public void refreshMsgListCache(MessageSendType messageSendType, Long sendId) {
        List<MessageText> messageTextList = messageTextMapper.selectBySendId(sendId);
        if (CollectionUtil.isEmpty(messageTextList)) return;
        Map<String, MessageTextVO> resultMap = new HashMap<>();
        for (MessageText messageText : messageTextList) {
            MessageTextVO messageTextVO = new MessageTextVO();
            BeanUtil.copyProperties(messageText, messageTextVO);
            messageTextVO.setTextId(messageText.getTextId());
            resultMap.put(getMessageDetailKey(messageText.getTextId()), messageTextVO);
        }

        String sendKey = getSenderCacheKey(messageSendType, sendId);
        List<Long> textIdList = messageTextList.stream().map(MessageText::getTextId).toList();
        redisService.rightPushAll(sendKey, textIdList);
        redisService.multiSet(resultMap);
    }

    public List<MessageTextVO> getUserMsgList(BaseQueryTableDTO queryTableDTO) {
        return getMsgList(MessageSendType.USER, queryTableDTO, ThreadLocalUtil.getUserId());
    }

    public List<MessageTextVO> getMsgList(MessageSendType messageSendType,  BaseQueryTableDTO queryTableDTO, Long sendId) {
        int start = (queryTableDTO.getPageNum() - 1) * queryTableDTO.getPageSize();
        int end = start + queryTableDTO.getPageSize() - 1; //下标需要 -1
        String senderCacheKey = getSenderCacheKey(messageSendType, sendId);
        List<Long> sendIdList = redisService.getCacheListByRange(senderCacheKey, start, end, Long.class);
        List<MessageTextVO> messageTextVOS = getCacheSendList(senderCacheKey, start, end);
        if (CollectionUtil.isEmpty(messageTextVOS) || messageTextVOS.size() != sendIdList.size()) {
            // 说明为空或者有某一个详情没获取到 刷新在获取
            refreshMsgListCache(messageSendType, sendId);
            messageTextVOS = getCacheSendList(senderCacheKey, start, end);
        }
        return messageTextVOS;
    }

    public void delByTextId(Long textId) {
        String userMessageListKey = getUserMessageListKey(ThreadLocalUtil.getUserId());
        redisService.removeForList(userMessageListKey, textId);
        redisService.deleteObject(getMessageDetailKey(textId));
    }


    // 通过key获取到封装好的列表
    private List<MessageTextVO> getCacheSendList(String senderCacheKey, int start, int end) {
        List<Long> sendIdList = redisService.getCacheListByRange(senderCacheKey, start, end, Long.class);
        List<String> sendIdKeyList = sendIdList.stream().map(this::getMessageDetailKey).toList();
        return redisService.multiGet(sendIdKeyList, MessageTextVO.class);
    }

    /**
     * 获取发送人存储在缓存的Key
     */
    private String getSenderCacheKey(MessageSendType messageSendType, Long sendId) {
        switch (messageSendType) {
            case USER: return getUserMessageListKey(sendId);
        }
        return "";
    }


    private String getUserMessageListKey(Long userId) {
        return CacheConstants.USER_MESSAGE_LIST + userId;
    }

    private String getMessageDetailKey(Long messageTextId) {
        return CacheConstants.MESSAGE_DETAIL + messageTextId;
    }
}
